package com.dingding.order.core.cancel.biz.impl;

import java.math.BigDecimal;
import java.util.List;

import javax.annotation.Resource;

import org.apache.http.HttpStatus;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.dingding.common.core.base.dto.AbstractResponse;
import com.dingding.common.core.base.dto.ResponseEntity;
import com.dingding.common.core.beans.Useraccount;
import com.dingding.common.core.beans.Userordert;
import com.dingding.common.core.config.ServiceCode;
import com.dingding.common.core.config.SystemConfig;
import com.dingding.common.core.model.push.PushModel;
import com.dingding.common.core.push.pushmsg.PushData;
import com.dingding.common.core.push.pushmsg.PushMsg;
import com.dingding.common.core.sms.model.MessageModel;
import com.dingding.common.core.util.DateFormatUtil;
import com.dingding.common.core.util.JSONUtil;
import com.dingding.common.core.util.ToolUtil;
import com.dingding.common.core.util.paravalidate.ValiResult;
import com.dingding.common.core.util.paravalidate.ValidateUtil;
import com.dingding.facade.account.user.service.IUserAccountService;
import com.dingding.facade.queue.dto.msg.MessageRequestsDTO;
import com.dingding.facade.queue.dto.push.PushRequestDTO;
import com.dingding.facade.queue.enums.ClientType;
import com.dingding.facade.queue.enums.PushType;
import com.dingding.facade.queue.facade.IQueueFacade;
import com.dingding.facade.user.dto.userinfo.ResUserInfoByCancelOrderDTO;
import com.dingding.facade.user.service.IUserAccountFacade;
import com.dingding.facade.user.service.IUserInfoFacade;
import com.dingding.facade.user.service.IUserLoginFacade;
import com.dingding.facade.user.service.userinfo.IGetUserInfoFacade;
import com.dingding.facde.activity.dto.AttendActivityDTO;
import com.dingding.facde.activity.enums.AttendActivityEnum;
import com.dingding.facde.activity.service.IUserAttendActivityService;
import com.dingding.facde.coupon.ICouponService;
import com.dingding.order.code.CalculateDistanceCodeMsg;
import com.dingding.order.code.CancelOrderCodeMsg;
import com.dingding.order.code.order.OrderStatus;
import com.dingding.order.core.cancel.biz.ICancelOrderService;
import com.dingding.order.core.cancel.dao.ICancelUserOrderDao;
import com.dingding.order.core.cancel.dao.ICancelUserOrderTDao;
import com.dingding.order.dto.cancel.PushAutomaticCancelOrderDTO;
import com.dingding.order.dto.cancel.PushCancelOrderDTO;
import com.dingding.order.dto.cancel.ReqCancelOrderDTO;
import com.dingding.order.dto.cancel.ResCancelOrderDTO;

@Component("cancelOrderService")
public class CancelOrderServiceImpl extends AbstractResponse<ResCancelOrderDTO, ReqCancelOrderDTO>
		implements ICancelOrderService {

	Logger log = Logger.getLogger(CancelOrderServiceImpl.class);

	// 判断是正式环境还是测试环境，如果是测试环境，则不增加取消次数
	private boolean environmentParam = SystemConfig.isEnv_system();

	// 订单表
	@Resource(name = "cancelUserOrderDao")
	private ICancelUserOrderDao cancelUserOrderDao;

	// 订单临时表
	@Resource(name = "cancelUserOrderTDao")
	private ICancelUserOrderTDao cancelUserOrderTDao;

	// 用户账户操作服务接口
	@Resource(name = "userAccountService2")
	private IUserAccountFacade userAccountfacade;

	// 用户账户service
	@Resource(name = "userAccountService")
	private IUserAccountService userAccountService;

	// 用户详情facade
	@Resource(name = "userInfoService")
	private IUserInfoFacade userInfoFacade;

	@Resource(name = "queueService")
	private IQueueFacade queuefacade;

	// 用户登录facade
	@Resource(name = "userLoginFacade")
	private IUserLoginFacade userLoginFacade;

	@Resource(name = "couponService")
	private ICouponService couponService;

	// 用户参加活动服务
	@Resource(name = "userAttendActivityService")
	private IUserAttendActivityService userAttendActivityService; 
	
	// 用户信息服务
	@Resource(name = "getUserInfoFacade")
	private IGetUserInfoFacade getUserInfoFacade;
	
	/** 
	 * 
	 * @Title: cancelOrder 
	 * @Description: 取消用户订单总方法
	 * @param reqCancelOrder
	 * @author chenwei
	 * 
	 * 修改说明：
	 * 修改人：CHEHUANBO
	 * 修改原因：代码逻辑存在严重问题
	 * 修改时间：2016-06-13
	 * 修改版本：V2.2.0
	 * 
	*/
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public String cancelOrder(String requestData) {

		ResponseEntity<ResCancelOrderDTO> response = new ResponseEntity<ResCancelOrderDTO>();

		// 客户端请求参数
		ReqCancelOrderDTO reqCancelOrderDTO = super.parseRequestJson(requestData);

		// 1.验证请求参数
		if (!validateParam(response, reqCancelOrderDTO)) {
			return super.responseBeanToJson(response);
		}

		// 2.通过订单ID获取订单信息
		Userordert userordert = cancelUserOrderTDao.getUserOrder(reqCancelOrderDTO.getOid());

		// 验证订单状态是否符合取消条件
		if (!orderStatusValidate(userordert, response)) {
			return super.responseBeanToJson(response);
		}

		// 执行取消订单，取消失败返回消息
		if (!cancelOrder(reqCancelOrderDTO, userordert, response)) {
			return super.responseBeanToJson(response);
		}

		// 订单状态为已支付执行退款
		if (userordert.getOrderStatus() == OrderStatus.ORDER_STATUS_PAID) {
			// 退款
			boolean flag = refund(userordert, response);
			if (!flag) {// 退款失败，返回消息
				return super.responseBeanToJson(response);
			}
		}

		// 判断是否有优惠券
		if (ToolUtil.isNotBlank(userordert.getUcId())) {

			String ucid = userordert.getUcId();

			couponService.useCoupon(ucid, 2);
		}

		// 合乘订单处理
		carShareOrderOperation(reqCancelOrderDTO, userordert, response);

		// 推送消息和短信
		if (userordert.getOrderStatus() != OrderStatus.ORDER_STATUS_WAITING) {// 不是待抢单状态都推送消息和短信
			sendMessageAndPushMessage(userordert, reqCancelOrderDTO);
		}

		// 取消成功，如果订单为已抢单状态，执行消息推送
		response.setCode(HttpStatus.SC_OK);

		return super.responseBeanToJson(response);

	}

	/**
	 * 
	 * @Title: sendMessageByAutoCancelOrder 
	 * @Description: 自动取消给用户发送短信
	 * @param pushAutomaticCancelOrderDTO
	 * @author YHQ 
	 * @return void    返回类型
	 * 
	 */
	public void sendMessageByAutoCancelOrder(PushAutomaticCancelOrderDTO pushAutomaticCancelOrderDTO) {

		if (ToolUtil.isNotBlank(pushAutomaticCancelOrderDTO.getDriverPhone())) {

			// 司机发送短信内容
			MessageRequestsDTO driverDTO = new MessageRequestsDTO();

			driverDTO.setTelPhone(pushAutomaticCancelOrderDTO.getDriverPhone()); // 司机手机号
			driverDTO.setMessageContent(MessageModel.autoCancelOrder(pushAutomaticCancelOrderDTO.getDriverName(),
					pushAutomaticCancelOrderDTO.getIntegral())); // 司机发送短信内容

			// 给司机发送短信内容加入队列
			queuefacade.addMessageToQueue(JSONUtil.toJSONString(driverDTO));
		}

		if (ToolUtil.isNotBlank(pushAutomaticCancelOrderDTO.getPassengerPhone())) {

			// 乘客发送短信内容
			MessageRequestsDTO passengerDTO = new MessageRequestsDTO();

			passengerDTO.setTelPhone(pushAutomaticCancelOrderDTO.getPassengerPhone()); // 乘客手机号
			passengerDTO.setMessageContent(MessageModel.autoCancelOrder(pushAutomaticCancelOrderDTO.getPassengerName(),
					pushAutomaticCancelOrderDTO.getIntegral())); // 乘客发送短信内容

			// 给乘客发送短信内容加入队列
			queuefacade.addMessageToQueue(JSONUtil.toJSONString(passengerDTO));
		}

	}

	/**
	 * 
	 * @Title: pushMessageByAutoCancelOrder 
	 * @Description: 自动取消给用户推送消息
	 * @param pushAutomaticCancelOrderDTO
	 * @author YHQ 
	 * @return void    返回类型
	 * 
	 */
	public void pushMessageByAutoCancelOrder(PushAutomaticCancelOrderDTO pushAutomaticCancelOrderDTO) {

		/*----------------给司机推送-----------------*/

		if (ToolUtil.isNotBlank(pushAutomaticCancelOrderDTO.getDriverAliasId())) {

			// 给司机推送消息内容
			PushRequestDTO driverDTO = new PushRequestDTO();

			// 推送Bean
			PushData driverPushData = new PushData();

			// 推送序号(时间戳)
			driverPushData.setRequestNumber(DateFormatUtil.getTimeInMillis().toString());
			// 推送时间
			driverPushData.setRequestTime(DateFormatUtil.yyyy_MM_dd_HHmmss());
			// 模块
			driverPushData.setModular("cancelOrderPush");
			driverPushData.setResponseBody(pushAutomaticCancelOrderDTO);

			// 推送别名
			driverDTO.setAliasId(pushAutomaticCancelOrderDTO.getDriverAliasId());
			driverDTO.setAlert("订单因超时已自动取消");

			// 设备类型
			if (pushAutomaticCancelOrderDTO.getDriverEquipment().equals("Android")) {
				driverDTO.setClientType(ClientType.Android);
			} else if (pushAutomaticCancelOrderDTO.getDriverEquipment().equals("iOS")) {
				driverDTO.setClientType(ClientType.iOS);
			}

			// 消息推送类型
			driverDTO.setPushType(PushType.alert_msgcontent);

			// 推送类型
			driverDTO.setPushContent(JSONUtil.toJSONString(driverPushData));

			// 给司机推送
			queuefacade.addPushToQueue(JSONUtil.toJSONString(driverDTO));
		}

		/*-----------------------------------------给乘客推送-----------------------------------------------*/

		if (ToolUtil.isNotBlank(pushAutomaticCancelOrderDTO.getPassengerAliasId())) {

			// 给司机推送消息内容
			PushRequestDTO passengerDTO = new PushRequestDTO();

			// 推送Bean
			PushData passengerPushData = new PushData();

			// 推送序号(时间戳)
			passengerPushData.setRequestNumber(DateFormatUtil.getTimeInMillis().toString());
			// 推送时间
			passengerPushData.setRequestTime(DateFormatUtil.yyyy_MM_dd_HHmmss());
			// 模块
			passengerPushData.setModular("cancelOrderPush");
			passengerPushData.setResponseBody(pushAutomaticCancelOrderDTO);

			// 推送别名
			passengerDTO.setAliasId(pushAutomaticCancelOrderDTO.getPassengerAliasId());
			passengerDTO.setAlert("订单因超时已自动取消");

			// 设备类型
			if (pushAutomaticCancelOrderDTO.getPassengerEquipment().equals("Android")) {
				passengerDTO.setClientType(ClientType.Android);
			} else if (pushAutomaticCancelOrderDTO.getPassengerEquipment().equals("iOS")) {
				passengerDTO.setClientType(ClientType.iOS);
			}

			// 消息推送类型
			passengerDTO.setPushType(PushType.alert_msgcontent);

			// 推送类型
			passengerDTO.setPushContent(JSONUtil.toJSONString(passengerPushData));

			// 给乘客推送
			queuefacade.addPushToQueue(JSONUtil.toJSONString(passengerDTO));
		}

	}
	
	/**
	 * 
	 * @Title: pushNoticeMessageByAutoCancelOrder 
	 * @Description: 自动取消给用户推送通知消息
	 * @param pushNoticeMessageByAutoCancelOrder
	 * @author YHQ 
	 * @return void    返回类型
	 * 
	 */
	public void pushNoticeMessageByAutoCancelOrder(PushAutomaticCancelOrderDTO pushAutomaticCancelOrderDTO) {
		
		/*----------------给司机推送-----------------*/
		
		if (ToolUtil.isNotBlank(pushAutomaticCancelOrderDTO.getDriverAliasId())) {
			
			// 给司机推送消息内容
			PushRequestDTO driverDTO = new PushRequestDTO();
			
			// 推送Bean
			PushData driverPushData = new PushData();
			
			String driverContent = MessageModel.autoCancelOrder(pushAutomaticCancelOrderDTO.getDriverName(),pushAutomaticCancelOrderDTO.getIntegral());
			
			// 推送序号(时间戳)
			driverPushData.setRequestNumber(DateFormatUtil.getTimeInMillis().toString());
			// 推送时间
			driverPushData.setRequestTime(DateFormatUtil.yyyy_MM_dd_HHmmss());
			// 模块
			driverPushData.setModular("newsNoticePush");
			// 推送内容
			driverPushData.setResponseBody(PushModel.noticeModel(1, driverContent, null));
			
			// 推送别名
			driverDTO.setAliasId(pushAutomaticCancelOrderDTO.getDriverAliasId());
			driverDTO.setAlert("订单因超时已自动取消");
			
			// 设备类型
			if (pushAutomaticCancelOrderDTO.getDriverEquipment().equals("Android")) {
				driverDTO.setClientType(ClientType.Android);
			} else if (pushAutomaticCancelOrderDTO.getDriverEquipment().equals("iOS")) {
				driverDTO.setClientType(ClientType.iOS);
			}
			
			// 消息推送类型
			driverDTO.setPushType(PushType.msgcontent);
			
			// 推送类型
			driverDTO.setPushContent(JSONUtil.toJSONString(driverPushData));
			
			// 给司机推送
			queuefacade.addPushToQueue(JSONUtil.toJSONString(driverDTO));
		}
		
		/*-----------------------------------------给乘客推送-----------------------------------------------*/
		
		if (ToolUtil.isNotBlank(pushAutomaticCancelOrderDTO.getPassengerAliasId())) {
			
			// 给司机推送消息内容
			PushRequestDTO passengerDTO = new PushRequestDTO();
			
			// 推送Bean
			PushData passengerPushData = new PushData();
			
			String passengerContent = MessageModel.autoCancelOrder(pushAutomaticCancelOrderDTO.getPassengerName(),pushAutomaticCancelOrderDTO.getIntegral());
			
			// 推送序号(时间戳)
			passengerPushData.setRequestNumber(DateFormatUtil.getTimeInMillis().toString());
			// 推送时间
			passengerPushData.setRequestTime(DateFormatUtil.yyyy_MM_dd_HHmmss());
			// 模块
			passengerPushData.setModular("newsNoticePush");
			// 推送内容
			passengerPushData.setResponseBody(PushModel.noticeModel(1, passengerContent, null));
			
			// 推送别名
			passengerDTO.setAliasId(pushAutomaticCancelOrderDTO.getPassengerAliasId());
			passengerDTO.setAlert("订单因超时已自动取消");
			
			// 设备类型
			if (pushAutomaticCancelOrderDTO.getPassengerEquipment().equals("Android")) {
				passengerDTO.setClientType(ClientType.Android);
			} else if (pushAutomaticCancelOrderDTO.getPassengerEquipment().equals("iOS")) {
				passengerDTO.setClientType(ClientType.iOS);
			}
			
			// 消息推送类型
			passengerDTO.setPushType(PushType.msgcontent);
			
			// 推送类型
			passengerDTO.setPushContent(JSONUtil.toJSONString(passengerPushData));
			
			// 给乘客推送
			queuefacade.addPushToQueue(JSONUtil.toJSONString(passengerDTO));
		}
		
	}

	/**
	 * @Title: getDriverId
	 * @Description: 根据订单信息和乘客Id获取司机Id
	 * @param userordert 订单信息
	 * @author yhq
	 * @return String 返回类型
	 * @throws
	 */
	public String getDriverId(Userordert userordert) {

		// 创建一个司机Id对象
		String driverId = null;

		if (userordert.getOrderType() == 1) {
			driverId = userordert.getPlaceOrderUserId();
		} else {
			driverId = userordert.getGrabOrderUserId();
		}

		return driverId;
	}

	/**
	 * @Title: getPassengerId
	 * @Description: 根据订单信息和乘客Id获取司机Id
	 * @param userordert  订单信息
	 * @author yhq
	 * @return String 返回类型
	 * @throws
	 */
	public String getPassengerId(Userordert userordert) {

		// 创建一个司机Id对象
		String passengerId = null;

		if (userordert.getOrderType() == 1) {
			passengerId = userordert.getGrabOrderUserId();
		} else {
			passengerId = userordert.getPlaceOrderUserId();
		}

		return passengerId;
	}

	/**
	 * 
	 * 取消订单发送短信和推送消息总方法
	 * 
	 * @Title: sendMessageAndPushMessage  
	 * @author CHEHAUNBO
	 * 
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public void sendMessageAndPushMessage(Userordert userordert, ReqCancelOrderDTO reqCancelOrderDTO) {

		// 获取司机Id
		String driverId = null;
		// 获取乘客Id
		String passengerId = null;

		// 获取司机Id
		driverId = this.getDriverId(userordert, reqCancelOrderDTO.getUserID());

		if (userordert.getPlaceOrderUserId().equals(driverId) && ToolUtil.isNotBlank(userordert.getGrabOrderUserId())) {
			passengerId = userordert.getGrabOrderUserId();
		} else {
			passengerId = userordert.getPlaceOrderUserId();
		}

		// 主动取消的用户Id
		String activeCancelOrderUserId = null;
		// 要推送的用户Id
		String pushUserId = null;

		if (reqCancelOrderDTO.getCancelNumber() == 1) { // 司机主动取消
			activeCancelOrderUserId = passengerId;
			pushUserId = driverId;
		} else if (reqCancelOrderDTO.getCancelNumber() == 2) { // 乘客主动取消
			activeCancelOrderUserId = driverId;
			pushUserId = passengerId;
		}

		PushCancelOrderDTO pushCancelOrderDTO = cancelUserOrderTDao.getPushCancelOrderInfo(activeCancelOrderUserId,
				pushUserId);

		if (userordert.getOrderType() == 1) { // 车主下单

			if (userordert.getParOrderId() == null) {
				// 父订单Id
				pushCancelOrderDTO.setParentOrder(userordert.getOid());
				// 子订单Id
				pushCancelOrderDTO.setSubOrder(null);
			} else {
				// 父订单Id
				pushCancelOrderDTO.setParentOrder(userordert.getParOrderId());
				// 子订单Id
				pushCancelOrderDTO.setSubOrder(userordert.getOid());
			}

		} else { // 乘客下单

			if (userordert.getParOrderId() == null) {
				// 父订单Id
				pushCancelOrderDTO.setParentOrder(null);
				// 子订单Id
				pushCancelOrderDTO.setSubOrder(userordert.getOid());
			} else {
				// 父订单Id
				pushCancelOrderDTO.setParentOrder(userordert.getParOrderId());
				// 子订单Id
				pushCancelOrderDTO.setSubOrder(userordert.getOid());
			}

		}

		// 订单状态
		pushCancelOrderDTO.setOrderStatus(userordert.getOrderStatus());
		// 订单取消原因
		pushCancelOrderDTO.setCancelDesc(reqCancelOrderDTO.getCancelDesc());
		// 订单状态
		pushCancelOrderDTO.setOrderStatus(ServiceCode.ORDER_STATUS_CANCEL);
		// 订单类型
		pushCancelOrderDTO.setPublishType(1);
		
		// 取消订单 - 发送短信
		sendMessage(pushCancelOrderDTO,reqCancelOrderDTO);
		
		// 取消订单 - 推送消息
		pushMessage(pushCancelOrderDTO, userordert, reqCancelOrderDTO);

		// 取消订单 - 推送通知消息
		pushModelMessage(pushCancelOrderDTO, userordert, reqCancelOrderDTO);
		
	}

	/**
	 * 
	 * 取消订单发送短信
	 * 
	 * @Title: sendMessage 
	 * @param pushCancelOrderDTO 
	 * @author CHEHAUNBO
	 * 
	 */
	public void sendMessage(PushCancelOrderDTO pushCancelOrderDTO,ReqCancelOrderDTO reqCancelOrderDTO) {

		MessageRequestsDTO messageRequestsDTO = new MessageRequestsDTO();
		messageRequestsDTO.setTelPhone(pushCancelOrderDTO.getTellPhone());
		messageRequestsDTO.setMessageContent(
				MessageModel.cancelOrder(pushCancelOrderDTO.getPassengerName(), pushCancelOrderDTO.getCancelDesc(),reqCancelOrderDTO.getCancelNumber()));
		queuefacade.addMessageToQueue(JSONUtil.toJSONString(messageRequestsDTO));

	}

	/**
	 *  取消订单 - 推送消息
	 * 
	 * @Title: pushMessage 
	 * @param pushCancelOrderDTO    设定文件 
	 * @author CHEHAUNBO
	 * 
	 */
	public void pushMessage(PushCancelOrderDTO pushCancelOrderDTO, Userordert userordert,
			ReqCancelOrderDTO reqCancelOrderDTO) {

		// 推送Bean
		PushData pushData = new PushData();

		// 推送序号(时间戳)
		pushData.setRequestNumber(DateFormatUtil.getTimeInMillis().toString());
		// 推送时间
		pushData.setRequestTime(DateFormatUtil.yyyy_MM_dd_HHmmss());
		// 模块
		pushData.setModular("cancelOrderPush");

		// 推送内容
		pushData.setResponseBody(pushCancelOrderDTO);

		PushRequestDTO pushRequestDTO = new PushRequestDTO();
		pushRequestDTO.setAlert(PushMsg.CANCEL_ORDER);
		pushRequestDTO.setAliasId(pushCancelOrderDTO.getDriverId());
		pushRequestDTO.setPushContent(JSONUtil.toJSONString(pushData));
		pushRequestDTO.setPushType(PushType.alert_msgcontent);
		// 设备类型
		if (pushCancelOrderDTO.getLoginEquipment().equals("Android")) {
			pushRequestDTO.setClientType(ClientType.Android);
		} else if (pushCancelOrderDTO.getLoginEquipment().equals("iOS")) {
			pushRequestDTO.setClientType(ClientType.iOS);
		}

		queuefacade.addPushToQueue(JSONUtil.toJSONString(pushRequestDTO));

	}
	
	/**
	 *  取消订单 - 推送消息
	 * 
	 * @Title: pushMessage 
	 * @param pushCancelOrderDTO    设定文件 
	 * @author CHEHAUNBO
	 * 
	 */
	public void pushModelMessage(PushCancelOrderDTO pushCancelOrderDTO, Userordert userordert,
			ReqCancelOrderDTO reqCancelOrderDTO) {
		
		// 推送Bean
		PushData pushData = new PushData();
		
		String content = MessageModel.cancelOrder(pushCancelOrderDTO.getPassengerName(), pushCancelOrderDTO.getCancelDesc(),reqCancelOrderDTO.getCancelNumber());
		
		// 推送序号(时间戳)
		pushData.setRequestNumber(DateFormatUtil.getTimeInMillis().toString());
		// 推送时间
		pushData.setRequestTime(DateFormatUtil.yyyy_MM_dd_HHmmss());
		// 模块
		pushData.setModular("newsNoticePush");
		
		// 推送内容
		pushData.setResponseBody(PushModel.noticeModel(1, content, null));
		
		PushRequestDTO pushRequestDTO = new PushRequestDTO();
		
		// 别名
		pushRequestDTO.setAliasId(pushCancelOrderDTO.getDriverId());
		// 消息内容
		pushRequestDTO.setPushContent(JSONUtil.toJSONString(pushData));
		// 推送类型
		pushRequestDTO.setPushType(PushType.msgcontent);
		// 设备类型
		if (pushCancelOrderDTO.getLoginEquipment().equals("Android")) {
			pushRequestDTO.setClientType(ClientType.Android);
		} else if (pushCancelOrderDTO.getLoginEquipment().equals("iOS")) {
			pushRequestDTO.setClientType(ClientType.iOS);
		}
		
		queuefacade.addPushToQueue(JSONUtil.toJSONString(pushRequestDTO));
		
	}

	/**
	 * 
	 * @Title: carShareOrderOperation
	 * @Description: 处理合乘订单
	 * @param userordert 
	 * @author yuHaiQing
	 * @return void    返回类型
	 * 
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public void carShareOrderOperation(ReqCancelOrderDTO reqCancelOrderDTO, Userordert userordert,
			ResponseEntity<ResCancelOrderDTO> response) {

		/**
		 * oid 存储两种值
		 * 
		 * 1. 乘客下单，无人抢单，取消订单时oid为乘客下单的订单Id
		 * 
		 * 2. 司机下单或订单状态大于等于2的时候，该oid存储的为主订单Id
		 * 
		 */
		String oid = null;

		if (ToolUtil.isNotBlank(userordert.getParOrderId())) {
			oid = userordert.getParOrderId();
		} else {
			oid = userordert.getOid();
		}

		// 取消订单操作成功，获取合乘订单集合，判断当前取消订单是否为最后一个子订单，如果是则进行转账操作
		List<Userordert> sharOrderList = cancelUserOrderTDao.getAllCarShareOrder(oid);

		// 判断合乘订单中是否存在未完成订单
		if (sharOrderList != null && sharOrderList.size() > 0) {

			boolean isCompleteOrder = false; // 是否存在未完成订单 true:存在未完成订单
												// false:不存在未完成订单
			int completeOrderNumber = 0; // 完成订单数量

			for (Userordert order : sharOrderList) {

				// 是否存在未完成订单
				if (order.getIsCarShare() == 2 && order.getOrderStatus() < 4) {
					isCompleteOrder = true;
				}

				// 完成订单个数
				if (order.getOrderStatus() == 4) {
					completeOrderNumber += 1;
				}
			}

			// 合乘订单最后一个订单结束
			if (!isCompleteOrder) {
				confirmArrivalOperation(reqCancelOrderDTO, sharOrderList, response, completeOrderNumber);
			}

		}

	}

	/**
	 * 
	 * @Title: confirmArrivalOperation
	 * @Description: 确认到达操作(合乘订单中的其他订单进行转账操作)
	 * @param sharOrderList 合乘订单集合
	 * @param completeOrderNumber 合乘订单中完成订单数量
	 * @author yuHaiQing
	 * @return void    返回类型
	 * 
	 */
	public void confirmArrivalOperation(ReqCancelOrderDTO reqCancelOrderDTO, List<Userordert> sharOrderList,
			ResponseEntity<ResCancelOrderDTO> response, int completeOrderNumber) {

		// 遍历合乘订单，进行相应的操作
		for (int i = 0; i < sharOrderList.size(); i++) {

			Userordert carOrder = sharOrderList.get(i);

			// 完成订单进行转账操作
			if (carOrder.getOrderStatus() == 4) {

				// 获取司机id
				String driverId = null;
				// 乘客Id
				String passengerId = null;

				if (carOrder.getOrderType() == 1) { // 司机下单
					driverId = carOrder.getPlaceOrderUserId();
					passengerId = carOrder.getGrabOrderUserId();
				} else { // 乘客下单
					driverId = carOrder.getGrabOrderUserId();
					passengerId = carOrder.getPlaceOrderUserId();
				}

				// 根据合乘订单中的完成订单，进行转账操作
				if (completeOrderNumber == 1) { // 合乘订单中只有一个完成订单
					giveDriverMoney(reqCancelOrderDTO, response, driverId, passengerId, carOrder);
				} else if (completeOrderNumber > 1) { // 合乘订单中有两个或两个以上完成订单
					giveDriverMoneyByCarpool(reqCancelOrderDTO, response, driverId, passengerId, carOrder);
				}

			}

			// 删除主订单
			if (carOrder.getOrderStatus() == 1 || carOrder.getIsChildren() == 1) {
				cancelUserOrderTDao.deleteCurrentOrder(carOrder);
			}

		}
	}

	/**
	 * @Description: 给司机转账，并给乘客返还20%钱(合乘订单中有两个或两个以上订单)
	 * @author fengshuonan
	 * @return
	 * @return void
	 */
	public ResponseEntity<ResCancelOrderDTO> giveDriverMoneyByCarpool(ReqCancelOrderDTO reqCancelOrderDTO,
			ResponseEntity<ResCancelOrderDTO> response, String driverId, String passengerId, Userordert order) {

		Useraccount driverAccount = this.userAccountService.getUserAccount(driverId);

		if (driverAccount == null) {
			response.setCode(HttpStatus.SC_FORBIDDEN);
			response.setErrorMessage("车主id不正确!");
			return response;
		}

		// 给车主转账
		driverAccount.setCurrencyAmount(driverAccount.getCurrencyAmount().add(order.getTotalMoney()));

		// 给乘客返钱
		Useraccount passengerAccount = this.userAccountService.getUserAccount(passengerId);
		BigDecimal currentMoney = passengerAccount.getCurrencyAmount() == null ? new BigDecimal(0) : passengerAccount.getCurrencyAmount();
		passengerAccount.setCurrencyAmount(currentMoney.add(order.getTotalMoney().multiply(new BigDecimal(0.2))));

		// 添加累计信息
		addLeijiStat(reqCancelOrderDTO, driverAccount, passengerAccount, order);

		// 移除当前订单
		boolean flag = cancelUserOrderTDao.deleteCurrentOrder(order);

		if (!flag) {
			log.error("合乘订单 - 移除当前订单失败");
		}

		return response;
	}

	/**
	 * @Description: 给司机转账(合乘订单中只有一个订单)
	 * @author fengshuonan
	 * @return ResponseEntity<ConfirmArriveResDTO>
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	private ResponseEntity<ResCancelOrderDTO> giveDriverMoney(ReqCancelOrderDTO reqCancelOrderDTO,
			ResponseEntity<ResCancelOrderDTO> response, String driverId, String passengerId, Userordert order) {

		Useraccount driverAccount = this.userAccountService.getUserAccount(driverId);
		Useraccount passengerAccount = this.userAccountService.getUserAccount(passengerId);

		if (driverAccount == null || passengerAccount == null) {
			response.setCode(HttpStatus.SC_FORBIDDEN);
			response.setErrorMessage("车主id或乘客id不正确!");
			return response;
		}

		driverAccount.setCurrencyAmount(
				driverAccount.getCurrencyAmount().add(order.getTotalMoney()).add(new BigDecimal(0)).subtract(order.getCouponMoney()));

		// 添加累计信息
		addLeijiStat(reqCancelOrderDTO, driverAccount, passengerAccount, order);

		// 移除当前订单
		boolean flag = cancelUserOrderTDao.deleteCurrentOrder(order);

		if (!flag) {
			log.error("非合乘订单 - 移除当前订单失败");
		}

		return response;
	}

	/**
	 * @Description: 增加累计数据
	 * @param driver
	 *            车主账户
	 * @param passenger
	 *            乘客账户
	 * @author fengshuonan
	 * @return void
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	private void addLeijiStat(ReqCancelOrderDTO reqCancelOrderDTO, Useraccount driver, Useraccount passenger,
			Userordert order) {

		// 修改用户账户信息
		this.userAccountService.updateAccount(driver);
		this.userAccountService.updateAccount(passenger);

		// 增加交易记录详情
		this.userAccountService.addAccountDetail(passenger.getLoginId(), order.getTotalMoney(),
				order.getTotalMoney().subtract(order.getCouponMoney()).add(new BigDecimal("2")), order.getCouponMoney(), 2);
		this.userAccountService.addAccountDetail(driver.getLoginId(), order.getTotalMoney(), new BigDecimal("0"), new BigDecimal("0"), 1);

		if (environmentParam) {
			// 增加取消订单次数
			userLoginFacade.addCancelNumber(reqCancelOrderDTO.getUserID());
		}

	}

	/**
	 * 
	 * 取消订单
	 * 
	 * @Title: cancelOrder 
	 * @return boolean  true 成功 false 失败
	 * @author CHEHAUNBO
	 * 
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	private boolean cancelOrder(ReqCancelOrderDTO reqCancelOrderDTO, Userordert userordert,
			ResponseEntity<ResCancelOrderDTO> response) {

		String orderId = userordert.getOid();
		String parOrderId = userordert.getParOrderId();

		boolean flag = false;
		try {

			// 如果是子订单，取消订单时需要先判断子订单数量，如果是最后一个子订单，需要将所属的父订单也取消
			if (userordert.getIsChildren() == 2) {
				int count = cancelUserOrderTDao.getChildranCount(orderId);
				if (count <= 1) { // 已经是最后一个子订单，取消父订单
					flag = cancelUserOrderTDao.cancelOrder(reqCancelOrderDTO, parOrderId);
				}
			}
			flag = cancelUserOrderTDao.cancelOrder(reqCancelOrderDTO, orderId);

		} catch (Exception e) {
			log.info("取消订单失败！", e);
		}

		if (!flag) {
			response.setCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
			response.setErrorMessage(CancelOrderCodeMsg.CANCEL_ORDER_ERROR);
			response.setPromptMessage(CancelOrderCodeMsg.SERVER_ERROR);
		}

		return flag;

	}

	/**
	 * 
	 * 退款
	 * 
	 * 只有订单状态为已支付才执行退款操作
	 * 
	 * @Title: refund  
	 * @return boolean  true 成功 false 失败 
	 * @author CHEHAUNBO
	 * 
	 */
	private boolean refund(Userordert userordert, ResponseEntity<ResCancelOrderDTO> response) {

		int userOrderStatus = userordert.getOrderStatus();

		// 如果订单状态为待抢单或者待合乘状态但是选择的是不合乘无需退款
		if (userOrderStatus < OrderStatus.ORDER_STATUS_PAID) {
			return true;
		}

		// 实际退款金额 （订单总金额 ）
		BigDecimal money = userordert.getTotalMoney().add(new BigDecimal(2));
		// 获取退款用户ID
		String userId = null;

		if (userordert.getOrderType() == 1) {
			userId = userordert.getGrabOrderUserId();
		} else {
			userId = userordert.getPlaceOrderUserId();
		}

		// 执行退款
		boolean flag = userAccountService.refunds(userId, money);
		// 退款失败
		if (!flag) {
			response.setCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
			response.setErrorMessage(CancelOrderCodeMsg.PASSAGER_REFUND_ERROR);
			response.setPromptMessage(CancelOrderCodeMsg.SERVER_ERROR);
		}

		return flag;

	}

	/**
	 * 
	 * 验证客户端请求参数是否合法
	 * 
	 * @Title: validateParam 
	 * @author CHEHAUNBO
	 * @since V2.2.0
	 * 
	 * 
	 */
	private boolean validateParam(ResponseEntity<ResCancelOrderDTO> response, ReqCancelOrderDTO reqCancelOrderDTO) {

		ValiResult valiResult = ValidateUtil.validateBeanIsAvaliable(reqCancelOrderDTO, ReqCancelOrderDTO.class);

		if (!valiResult.isAvailable()) {// 参数为空
			response.setCode(HttpStatus.SC_FORBIDDEN);
			response.setErrorMessage(CalculateDistanceCodeMsg.DATA_NULL_PARAM_MESSAGE);
			return false;
		}

		return true;

	}

	/**
	 * @Title: getDriverId
	 * @Description: 根据订单信息和乘客Id获取司机Id
	 * @param userordert
	 *            订单信息
	 * @param passengerId
	 *            乘客Id
	 * @author yhq
	 * @return String 返回类型
	 * @throws
	 */
	public String getDriverId(Userordert userordert, String passengerId) {

		// 创建一个司机Id对象
		String driverId = null;

		if (userordert.getOrderType() == 2) {
			driverId = userordert.getPlaceOrderUserId();
		} else {
			driverId = userordert.getGrabOrderUserId();
		}

		return driverId;
	}

	/**
	 * 
	 * 验证订单状态
	 * 
	 * @Title: orderStatusValidate 
	 * @return  boolean true 成功  false 失败 
	 * @author CHEHAUNBO
	 * 
	 */
	private boolean orderStatusValidate(Userordert userordert, ResponseEntity<ResCancelOrderDTO> response) {

		if (userordert == null) { // 订单不存在

			response.setCode(HttpStatus.SC_FORBIDDEN);
			response.setErrorMessage(CancelOrderCodeMsg.ORDER_NOT_EXISTS);
			response.setPromptMessage(CancelOrderCodeMsg.ORDER_NOT_EXISTS);
			return false;
		} else if (userordert.getOrderStatus() == OrderStatus.ORDER_STATUS_COMPLETE) { // 订单已完成

			response.setCode(HttpStatus.SC_FORBIDDEN);
			response.setErrorMessage(CancelOrderCodeMsg.ORDER_COMPLETE_ERROR);
			response.setPromptMessage(CancelOrderCodeMsg.ORDER_COMPLETE_ERROR);

			return false;

		} else if (userordert.getOrderStatus() == OrderStatus.ORDER_STATUS_CANCEL) { // 订单已取消

			response.setCode(HttpStatus.SC_FORBIDDEN);
			response.setErrorMessage(CancelOrderCodeMsg.ORDER_CANCEL_ERROR);
			response.setPromptMessage(CancelOrderCodeMsg.ORDER_CANCEL_ERROR);

			return false;

		}

		return true;

	}

	public String getUserId(ReqCancelOrderDTO reqCancelOrderDTO, String driverId, String passengerId) {

		String pushUserId = "";

		if (reqCancelOrderDTO.getCancelNumber() == 1) { // 司机主动取消
			pushUserId = passengerId;
		} else if (reqCancelOrderDTO.getCancelNumber() == 2) { // 乘客主动取消
			pushUserId = driverId;
		}

		return pushUserId;
	}

	/** 
	 * 
	 * @Title: autoCancelOrder 
	 * @Description: 自动取消订单
	 * @author YHQ
	 * @return void
	 * 
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public void autoCancelOrder() {

		ResponseEntity<ResCancelOrderDTO> response = new ResponseEntity<ResCancelOrderDTO>();

		// 获取自动取消列表
		List<Userordert> userorderts = cancelUserOrderTDao.getUserOrderByAutoCancel();

		// 取消订单操作
		if (userorderts != null && userorderts.size() > 0) {

			// 取消参数
			ReqCancelOrderDTO reqCancelOrderDTO = new ReqCancelOrderDTO();

			reqCancelOrderDTO.setCancelDesc("订单超时，自动取消"); // 取消原因
			reqCancelOrderDTO.setCancelType(2); // 取消类型 1：用户取消 2：自动取消
			reqCancelOrderDTO.setUserType(0);

			for (Userordert userordert : userorderts) {

				reqCancelOrderDTO.setOid(userordert.getOid()); // 订单Id

				// 执行取消订单，取消失败返回消息 true:取消成功 false:取消失败
				boolean flag = cancelOrder(reqCancelOrderDTO, userordert, response);

				if (!flag) {
					continue;
				}

				// 判断是否有优惠券
				if (ToolUtil.isNotBlank(userordert.getUcId())) {

					String ucid = userordert.getUcId();

					couponService.useCoupon(ucid, 2);
				}

				// 合乘订单处理
				carShareOrderOperation(reqCancelOrderDTO, userordert, response);

				// 推送消息和短信
				if (userordert.getOrderStatus() < OrderStatus.ORDER_STATUS_PAID) {// 已支付之前的订单

					// 获取司机Id
					String driverId = this.getDriverId(userordert);
					// 获取乘客Id
					String passengerId = this.getPassengerId(userordert);

					BigDecimal integral = this.giveIntegral(driverId, userordert.getOid());
					
					// 创建通知类信息对象
					PushAutomaticCancelOrderDTO pushAutomaticCancelOrderDTO = new PushAutomaticCancelOrderDTO();
					
					// 补全通知类信息
					getPushAutomaticCancelOrderDTO(pushAutomaticCancelOrderDTO, userordert,passengerId, driverId);
					
					// 设置积分
					pushAutomaticCancelOrderDTO.setIntegral(integral);
					// 发布订单类型(1:顺风车 2:出租车 3:专车4:一口价)
					pushAutomaticCancelOrderDTO.setPublishType(1);

					// 推送短信
					sendMessageByAutoCancelOrder(pushAutomaticCancelOrderDTO);
					// 推送消息
					pushMessageByAutoCancelOrder(pushAutomaticCancelOrderDTO);
					// 通知推送
					pushNoticeMessageByAutoCancelOrder(pushAutomaticCancelOrderDTO);
				}

			}
		}
	}

	/**
	 * 
	 * @Title: giveIntegral 
	 * @Description: 赠送积分
	 * @param driverId 司机Id
	 * @author YHQ 
	 * @since V2.3.0
	 * @return void    返回类型
	 * 
	 */
	public BigDecimal giveIntegral(String driverId,String oid){
		
		AttendActivityDTO attendActivityDTO = new AttendActivityDTO();
		attendActivityDTO.setUserId(driverId); // 司机ID
		attendActivityDTO.setAttendType(AttendActivityEnum.CANCEL_ORDER); // 参与条件
		
		// 添加积分
		BigDecimal integral = userAttendActivityService.userAttendActivity(attendActivityDTO);
		
		if (integral.compareTo(new BigDecimal(0)) != 0) {
			// 将参加活动所赠积分添加到订单表中
			cancelUserOrderDao.updateCurrentOrderReceiveIntegral(integral.intValue(),oid);
		}
		
		return integral;
	}

	
	
	/**
	 * 
	 * @Title: getPushAutomaticCancelOrderDTO 
	 * @Description: 转换数据 
	 * @param pushAutomaticCancelOrderDTO 通知信息
	 * @param userordert 订单信息
	 * @author YHQ 
	 * @return void    返回类型
	 * 
	 */
	public void getPushAutomaticCancelOrderDTO(PushAutomaticCancelOrderDTO pushAutomaticCancelOrderDTO,
			Userordert userordert,String passengerId, String driverId) {

		// 获取乘客信息
		if(ToolUtil.isNotBlank(passengerId)){
			 ResUserInfoByCancelOrderDTO passengerInfo = getUserInfoFacade.getUserInfoByCancelOrder(passengerId);
			 
			 if(passengerInfo != null){
				 
				 // 乘客Id
				 pushAutomaticCancelOrderDTO.setPassengerId(passengerInfo.getUid());
				 // 乘客推送Id
				 pushAutomaticCancelOrderDTO.setPassengerAliasId(passengerInfo.getAliasId());
				 // 乘客设备类型
				 pushAutomaticCancelOrderDTO.setPassengerEquipment(passengerInfo.getLoginEquipment() == 1 ? "iOS" : "Android");
				 // 乘客姓名
				 pushAutomaticCancelOrderDTO.setPassengerName(passengerInfo.getNickName());
				 // 乘客电话
				 pushAutomaticCancelOrderDTO.setPassengerPhone(passengerInfo.getTellphone());
			 }
		}
		
		// 获取司机信息
		if(ToolUtil.isNotBlank(driverId)){
			ResUserInfoByCancelOrderDTO driverInfo = getUserInfoFacade.getUserInfoByCancelOrder(driverId);
			
			 if(driverInfo != null){
				 
				 // 乘客Id
				 pushAutomaticCancelOrderDTO.setDriverId(driverInfo.getUid());
				 // 乘客推送Id
				 pushAutomaticCancelOrderDTO.setDriverAliasId(driverInfo.getAliasId());
				 // 乘客设备类型
				 pushAutomaticCancelOrderDTO.setDriverEquipment(driverInfo.getLoginEquipment() == 1 ? "iOS" : "Android");
				 // 乘客姓名
				 pushAutomaticCancelOrderDTO.setDriverName(driverInfo.getNickName());
				 // 乘客电话
				 pushAutomaticCancelOrderDTO.setDriverPhone(driverInfo.getTellphone());
			 }
		}
		
		pushAutomaticCancelOrderDTO.setOrderStatus(5);// 订单状态
		pushAutomaticCancelOrderDTO.setOrderType(userordert.getOrderType());// 下单类型
		pushAutomaticCancelOrderDTO.setDistance(userordert.getDistance());// 里程
		pushAutomaticCancelOrderDTO.setAlipayMoney(userordert.getAlipayMoney());// 第三方支付金额
		pushAutomaticCancelOrderDTO.setPayMoney(userordert.getPayMoney());// 叮币支付金额
		pushAutomaticCancelOrderDTO.setCouponMoney(userordert.getCouponMoney());// 优惠金额
		pushAutomaticCancelOrderDTO.setCreateTime(userordert.getCreateTime());// 下单时间
		pushAutomaticCancelOrderDTO.setSetOutTime(userordert.getSetOutTime());// 出发时间
		pushAutomaticCancelOrderDTO.setStartAddress(userordert.getStartAddress());// 起点
		pushAutomaticCancelOrderDTO.setEndAddress(userordert.getEndAddress());// 终点
		pushAutomaticCancelOrderDTO.setIsLongDistance(userordert.getIsLongDistance());// 1:普通
																						// 2:长途
		pushAutomaticCancelOrderDTO.setUcId(userordert.getUcId());// 用户优惠券Id
		pushAutomaticCancelOrderDTO.setTotalMoney(userordert.getTotalMoney());// 订单里程

		if (userordert.getOrderType() == 1) { // 车主下单

			if (userordert.getParOrderId() == null) {
				// 父订单Id
				pushAutomaticCancelOrderDTO.setParentOrder(userordert.getOid());
				// 子订单Id
				pushAutomaticCancelOrderDTO.setSubOrder(null);
			} else {
				// 父订单Id
				pushAutomaticCancelOrderDTO.setParentOrder(userordert.getParOrderId());
				// 子订单Id
				pushAutomaticCancelOrderDTO.setSubOrder(userordert.getOid());
			}

		} else { // 乘客下单

			if (userordert.getParOrderId() == null) {
				// 父订单Id
				pushAutomaticCancelOrderDTO.setParentOrder(null);
				// 子订单Id
				pushAutomaticCancelOrderDTO.setSubOrder(userordert.getOid());
			} else {
				// 父订单Id
				pushAutomaticCancelOrderDTO.setParentOrder(userordert.getParOrderId());
				// 子订单Id
				pushAutomaticCancelOrderDTO.setSubOrder(userordert.getOid());
			}

		}

	}

}
